#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "qi_func.h"
#include "qi_vars.h"


struct qi_funccontainer qi_funcs;

void qi_initfuncs()
{
	memset(qi_funcs.array, 0, sizeof(qi_funcs.array));
}

void qi_freefuncs()
{
	int i;
	for(i = 0; i < Q_HASH_TABLE_SIZE; ++i)
	{
		struct qi_func* tmp1 = qi_funcs.array[i];
		while(tmp1)
		{
			struct qi_func* tmp2 = tmp1->next;
			free(tmp1);
			tmp1 = tmp2;
		}
	}
}

struct qi_func* qi_funclookup(const char* const name)
{
	struct qi_func * tmp = qi_funcs.array[q_hashname(name)];

	for(; tmp; tmp = tmp->next)
		if(!strncmp(tmp->name, name, Q_MAX_SYMBOL_LENGTH))
			return tmp;
	return NULL;
}

int qi_addfunc(const char* const name, const char* const returntype, int num_args, const char** argname, int* argref, int* argconst)
{
	int i;
	struct qi_func *func;
	if(qi_funclookup(name))
		return Q_STATUS_ALREADYEXISTS;
	if(!(func = (struct qi_func*)malloc(sizeof(struct qi_func))))
		return Q_STATUS_FATAL;
	strncpy(func->name, name, Q_MAX_SYMBOL_LENGTH);
	func->next = NULL;
	if(!(func->returntype = qi_typelookup(returntype)))
	{
		free(func);
		return -1; //
	}
	if(num_args > 0)
	{
		if(!(func->args = (struct qi_arg*)malloc(sizeof(struct qi_arg) * num_args)))
		{
			free(func);
			return -1;
		}

		for(i = 0; i < num_args; ++i)
		{
			if((func->args[i].ptr = qi_typelookup(argname[i])))
			{
				func->args[i].reference = argref[i];
				func->args[i].constant = argconst[i];
			}
			else
			{
				free(func->args);
				free(func);
				return -1; //
			}
		}
	}
	else
		func->num_args = 0;
	return 0;
}











